namespace CRM_Perf_BenchMark
{
    using System;
    using System.Collections.Generic;
    using Microsoft.VisualStudio.TestTools.WebTesting;
    using System.Net;
    using System.Text;
    using System.Xml;
    
    /// <summary>
    /// 1.  Start at Sales homepage
    /// 2.	Select Opportunities
    /// 3.	Select a random view
    /// 4.	Click right button at bottom till last page
    /// </summary>
    
    public class RefreshGridOpportunity : CrmWebTest
    {
        public void RefreshGridOpportunity_PreWebTest(object sender, PreWebTestEventArgs e)
        {
            EntityRequest er = new EntityRequest();
            er.Type = EntityNames.Users;
            er.ReturnAs = EntityNames.Users;
            er.ParentID = EntityManager.Instance.OrgId;

            System.Collections.Hashtable Props = new System.Collections.Hashtable();

            if (e.WebTest.Context.ContainsKey("UserRole"))
            {
                Props.Add("role", e.WebTest.Context["UserRole"]);
            }
            
            EntityRequest OpportunityEr = new EntityRequest();
            OpportunityEr.Type = EntityNames.Opportunities;
            OpportunityEr.ParentID = Guid.NewGuid();
            OpportunityEr.ReturnAs = EntityNames.Opportunities;

            Props.Add(EntityNames.Opportunities, new EntityRequest[] { OpportunityEr });

            er.Props = Props;

            System.Collections.Hashtable Entities = EntityManager.Instance.GetEntities(er);

            user = (CRMEntity)Entities[EntityNames.Users];
            crmServer = user["CrmServer"];
            tokenKey = EntityManager.Instance.ReadTokenKey(user["organizationid"]);


            e.WebTest.UserName = user["domainName"];
            e.WebTest.Password = user["userpassword"];            
        }
        
        public void RefreshGridOpportunity_PostWebTest(object sender, PostWebTestEventArgs e)
        {
            EntityManager.Instance.FreeEntity(user);
        }

        public RefreshGridOpportunity()
        {
            WebRequest.RegisterPrefix("crm", new crmRequestFactory());
            numGen = new Random();
            randomView = numGen.Next(5); // 2
            currentViewName = viewNames[randomView];
            currentViewId = viewIds[randomView];
            gridXml = GridXmlHelper.OpportunityPageView(-1, currentViewId, null);

            this.Proxy = null;            
            PreWebTest += new EventHandler<PreWebTestEventArgs>(RefreshGridOpportunity_PreWebTest);
            PostWebTest += new EventHandler<PostWebTestEventArgs>(RefreshGridOpportunity_PostWebTest);
        }

        public override IEnumerator<WebTestRequest> GetRequestEnumerator()
        {

            _root_homepage_aspx homepage = new _root_homepage_aspx(user);
            homepage.etc = 4;
            yield return (homepage);

            bool moreRecords;
            int pageNum = 1;

            do
            {
                // Initialize moreRecords to false for every test. If next page exists, 
                // moreRecords is set to true to continue.
                moreRecords = false;
                string pagingCookie = null;
                AppGridWebService.AppGridWebService ag = new AppGridWebService.AppGridWebService();
                CrmRequest wtr = null;

                this.BeginTransaction(currentViewName + " pNum " + pageNum.ToString());

                if (pageNum == 1)
                {
                    try { ag.Reset(gridXml, gridId); }
                    catch (crmException x)
                    {
                        wtr = (CrmRequest)x.wtr;
                        wtr.Url = Utils.ReplaceServerName(wtr.Url, user);

                        string urlPath = wtr.Url.Remove(0, crmServer.Length);
                        urlPath = urlPath.Remove(0, user["organizationName"].Length + 1);

                        rpcInfo = Utils.GenerateWRPCToken(urlPath, user, tokenKey);

                        headerItem = new WebTestRequestHeader();
                        headerItem.Name = "crmwrpctokentimestamp";
                        headerItem.Value = rpcInfo.timeStamp.ToString();
                        wtr.Headers.Add(headerItem);
                        headerItem = new WebTestRequestHeader();
                        headerItem.Name = "crmwrpctoken";
                        headerItem.Value = rpcInfo.token;
                        wtr.Headers.Add(headerItem);
                        wtr.Method = "Post";
                    }
                    yield return (wtr);
                }
                else
                {
                    try { ag.Refresh(gridXml); }
                    catch (crmException x)
                    {
                        wtr = (CrmRequest)x.wtr;
                        wtr.Url = Utils.ReplaceServerName(wtr.Url, user);

                        string urlPath = wtr.Url.Remove(0, crmServer.Length);
                        urlPath = urlPath.Remove(0, user["organizationName"].Length + 1);

                        rpcInfo = Utils.GenerateWRPCToken(urlPath, user, tokenKey);

                        headerItem = new WebTestRequestHeader();
                        headerItem.Name = "crmwrpctokentimestamp";
                        headerItem.Value = rpcInfo.timeStamp.ToString();
                        wtr.Headers.Add(headerItem);
                        headerItem = new WebTestRequestHeader();
                        headerItem.Name = "crmwrpctoken";
                        headerItem.Value = rpcInfo.token;
                        wtr.Headers.Add(headerItem);
                        wtr.Method = "Post";
                    }
                    yield return (wtr);
                }

                this.EndTransaction(currentViewName + " pNum " + pageNum.ToString());

                int pos = wtr.lastResponse.BodyString.IndexOf(@"pagingCookie=""");
                if (pos > 0)
                {
                    int endPos = wtr.lastResponse.BodyString.IndexOf('"', pos + 15);
                    string pagingCookieOld = pagingCookie;
                    pagingCookie = wtr.lastResponse.BodyString.Substring(pos + 14, endPos - (pos + 14));
                    if (pagingCookie == pagingCookieOld)
                        throw new Exception("PagingCookie returned is same as previous one. Can potentially lead to infinite loop, excepting out");
                }
                if (wtr.lastResponse.BodyString.Contains(@"morerecords=""1"""))
                {
                    moreRecords = true;
                    pageNum++;
                    gridXml = GridXmlHelper.OpportunityPageViewRefresh(pageNum, currentViewId, pagingCookie);
                }
            } while (moreRecords == true);
        }

        private string gridXml;
        private string gridId = "crmGrid";

        private CRMEntity user;
        private string crmServer;
        private string tokenKey;

        private string[] viewNames = new string[] { "Closed opportunities view",            "My open opportunities view",           "Open opportunities view",              "Opportunities closing next month",     "Opportunities opened last week",       "Opportunities opened this week"};
        private string[] viewIds   = new string[] { "00000000-0000-0000-00AA-000010003006", "00000000-0000-0000-00AA-000010003000", "00000000-0000-0000-00AA-000010003001", "00000000-0000-0000-00AA-000010003002", "00000000-0000-0000-00AA-000010003003", "00000000-0000-0000-00AA-000010003004" };
        private Random numGen;
        private int randomView;

        private string currentViewName;
        private string currentViewId;

        private WRPCInfo rpcInfo;
        private WebTestRequestHeader headerItem;
    }
}